package domain.services;

import domain.constants.UserJwtConstants;
import domain.entities.User;
import infrastructure.Repository;
import internal.InternalResult;
import internal.UserJwt;
import org.apache.log4j.Logger;
import util.MD5Helper;
import util.StringValidator;
import util.UserJwtHelper;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 用户领域服务
 *
 * @author wyl
 */
public final class UserDomainService {
    public static UserDomainService Instance = new UserDomainService();
    private final Logger logger = Logger.getLogger(this.getClass());
    private Repository<User> repository;

    public UserDomainService() {
        try {
            this.repository = new Repository<User>() {
            };
        } catch (Exception e) {
            System.out.println("UserDomainService创建失败");
            e.printStackTrace();
        }
    }

    public InternalResult register(String username, String password, String nickName) {
        try {
            if (StringValidator.isBlank(username)) {
                return InternalResult.crateError("用户名不能为空", false);
            }
            if (StringValidator.isBlank(password)) {
                return InternalResult.crateError("密码不能为空", false);
            }
            if (StringValidator.isBlank(nickName)) {
                return InternalResult.crateError("昵称不能为空", false);
            }
            if (checkUsernameRegister(username)) {
                return InternalResult.crateError("用户名已经被注册", false);
            }
            if (repository.add(new User(username, nickName, password))) {
                return InternalResult.createSuccess();
            }
        } catch (Exception e) {
            logger.error(e);
            return InternalResult.crateError(e.getMessage(), true);
        }

        return InternalResult.crateError("未知原因添加失败", false);
    }

    public InternalResult login(String username, String password) {
        try {
            if (StringValidator.isBlank(username)) {
                return InternalResult.crateError("用户名不能为空", false);
            }
            if (StringValidator.isBlank(password)) {
                return InternalResult.crateError("密码不能为空", false);
            }
            Collection<User> users = repository.queryByProp("username", username);
            Optional<User> optional = users.stream().findFirst();
            if (optional.isPresent()) {
                User u = optional.get();
                //将输入值进行md5加密与数据库中进行比对
                String e = MD5Helper.encrypt(password);
                if (e.equals(u.getPassword())) {
                    //取消上一个令牌，使之前的令牌失效
                    if (CancelPreviousToken(u)) {
                        return InternalResult.createSuccessResult(u);
                    }
                    return InternalResult.crateError("登录失败,系统错误", false);
                }
            }
            return InternalResult.crateError("登录失败,用户名或者密码错误", false);
        } catch (Exception e) {
            logger.error(e);
            return InternalResult.crateError(e.getMessage(), true);
        }

    }

    public Collection<User> getAllUser() {
        return repository.queryAll();
    }

    public boolean deleteUserById(String userId) {
        return repository.deleteById(userId);
    }

    public boolean updateUser(User u) {
        return repository.update(u);
    }


    public InternalResult tryLogin(String token) {
        UserJwt userJwt = UserJwtHelper.ParseToken(token);
        //如果token有效，则使之前的token失效并重新颁发token
        if (userJwt.isEffective()) {
            String userId = userJwt.getUserId();
            User u = repository.queryById(userId);
            if (u != null) {
                //JWTVersion一直说明其他人还未登录过，token有效
                if (userJwt.getJwtVersion().equals(u.getJwtVersion().toString())) {
                    CancelPreviousToken(u);
                } else {
                    return InternalResult.crateError("用户身份信息失效，回到登录界面", false);
                }
                return InternalResult.createSuccessResult(u);
            }
        }

        return InternalResult.crateError(userJwt.getInvalidReason(), false);
    }


    //构建用户jwt
    public InternalResult buildUserToken(User u) {
        Map<String, Object> claims = new HashMap<>();
        claims.put(UserJwtConstants.USER_JWT_VERSION_CLAIM_KEY, u.getJwtVersion());
        claims.put(UserJwtConstants.USER_ID_CLAIM_KEY, u.getId());
        return UserJwtHelper.buildJwt(claims);
    }

    public boolean CancelPreviousToken(User u) {
        u.jwtVersionIncrease();
        return updateUser(u);
    }


    /**
     * 检查用户名是否被注册
     *
     * @param username 用户名
     * @return 是否注册
     */
    public boolean checkUsernameRegister(String username) {
        Collection<User> users = repository.queryByProp("username", username);
        return users.size() > 0;
    }

}
